
#include "unixhead.h"

#include <iostream>

using std::cout;
using std::endl;
using std::string;

#include <workflow/WFFacilities.h>
#include <workflow/WFHttpServer.h>

static WFFacilities::WaitGroup waitGroup(1);

struct SeriesContext
{
    string _password;
    protocol::HttpResponse * _resp;
};

void sighandler(int num)
{
    printf("sig number %d is comming\n", num);
    waitGroup.done();
}

void redisCallback(WFRedisTask * );

void httpCallback(WFHttpTask * serverTask)
{
    cout << "httpCallback is running" << endl;
    SeriesContext * context = (SeriesContext*)series_of(serverTask)->get_context();
    if(context) {
        delete context;
        context = nullptr;
    }
}

void process(WFHttpTask * serverTask)
{
    cout << "process is running" << endl;
    serverTask->set_callback(httpCallback);
    auto req = serverTask->get_req();
    auto resp = serverTask->get_resp();
    string method = req->get_method();
    string uri = req->get_request_uri();
    cout << "method:" << method << endl;
    cout << "uri:" << uri << endl;

    if(method == "GET" && uri == "/login") {
        //读取服务器本地的postform.html文件
        int fd = open("postform.html", O_RDONLY);
        if(fd < 0) {
            perror("open");
            return;
        }
        char buff[1024] = {0};
        int ret = read(fd, buff, sizeof(buff));
        //读取到buff中的内容，就是要返回给客户端的消息体
        resp->append_output_body(buff, ret);
        resp->add_header_pair("Content-Type", "text/html");
        resp->add_header_pair("Content-Length", std::to_string(ret).c_str());
    } else if(method == "POST" && uri == "/login") {
        //解析请求，获取请求报文的消息体body
        const void * body;
        size_t sz = 0;
        req->get_parsed_body(&body, &sz);
        string strBody((const char *)body, sz);
        string nameKV = strBody.substr(0, strBody.find("&"));
        string passwdKV = strBody.substr(strBody.find("&") + 1);
        string name = nameKV.substr(nameKV.find("=") + 1);
        string passwd = passwdKV.substr(passwdKV.find("=") + 1);
        cout << "name:" << name << endl;
        cout << "passwd:" << passwd << endl;

        //设置共享数据
        SeriesContext * context = new SeriesContext;
        context->_password = passwd;
        context->_resp = serverTask->get_resp();
        series_of(serverTask)->set_context(context);
        //添加redis任务
        auto redisTask = WFTaskFactory::create_redis_task(
                            "redis://127.0.0.1:6379", 1, redisCallback);
        string command("HGET");
        std::vector<string> params{"student", name};
        redisTask->get_req()->set_request(command, params);
        series_of(serverTask)->push_back(redisTask);
    }
}

void test0()
{
    signal(SIGINT, sighandler);

    WFHttpServer server(process);

    if(server.start(8888) == 0) {
        waitGroup.wait();
        server.stop();
    } else {
        cout << "server start failed" << endl;
    }
}


int main()
{
    test0();
    return 0;
}

void redisCallback(WFRedisTask * redisTask)
{
    //1. 错误的检测
    //
    //2. 进行验证,并生成响应信息
    SeriesContext * context = (SeriesContext *)series_of(redisTask)->get_context();

    protocol::RedisValue result;
    redisTask->get_resp()->get_result(result);
    if(result.is_string()) {
        cout << "value is string: " << result.string_value() << endl;
        if(result.string_value() == context->_password) {
            //登录验证成功
            context->_resp->append_output_body("Login Success!");
        } else {
            //登录验证失败
            context->_resp->append_output_body("Login Failded!");
        }
    } else {
        //登录验证失败
        context->_resp->append_output_body("Login Failded!");
    }
    context->_resp->add_header_pair("Server", "Workflow http server");
    context->_resp->add_header_pair("Content-Type", "text/plain");
    context->_resp->set_http_version("HTTP/1.1");
    context->_resp->set_status_code("200");
    context->_resp->set_reason_phrase("OK");
}
